home *** CD-ROM | disk | FTP | other *** search
/ Beginning Mac Programming / Beginning Mac Programming.bin / Open Me for REALbasic 3 / REALbasic 3.2 / Example Projects / Techniques / Examples by Thomas Tempelmann / TT's CatSearch-Plugin / Source Code (CW Pro 3) / Plugin Source.cpp < prev   
Text File  |  1999-03-08  |  8KB  |  247 lines

  1. /*
  2.  * Sample-Plugin showing how to pass structs from and to REALbasic-Plugins
  3.  *
  4.  * This plugin actually is useful:
  5.  *  It allows you to search for files with a certain file type and/or file creator.
  6.  *  This search is very fast (uses the same low-level function as the Finder's
  7.  *  Find File aka Sherlock uses). However, some File Systems do not support this
  8.  *  fast search method (called CatSearch): On Floppy Disks and on CD-ROMs with
  9.  *  a ISO 9660 format this function might not work (depending on the File System
  10.  *  driver you've installed). On plain HFS/HFS+ volumes, it should always work.
  11.  *
  12.  * This plugin works only with MacOS, neither with Windows nor with Java.
  13.  *
  14.  * The enclosed project file was created using CodeWarrior Pro 3.
  15.  * There's also a REALbasic Demo project that shows how to use this plugin.
  16.  *
  17.  * This code is freeware, you may use and extend it as you like.
  18.  *
  19.  * It was written on Feb 9, 99 by Thomas Tempelmann.
  20.  * More RB-related stuff can be found here: <http://www.tempel.org/rb>
  21.  *
  22.  * Update by TT on 12 Feb 99:
  23.  *  • IsRemoteVolume() prevents crash by setting ioNamePtr to zero
  24.  *
  25.  * Update by TT on 8 Mar 99:
  26.  *  • Renamed the plugin from "CatalogSearch-Plugin" to "TT's CatSearch-Plugin".
  27.  *  • Added some more Catsearch-related functions.
  28.  *  • Moved Catsearch-unrelated functions into a new plugin (called "TT's FileMgr-Plugin").
  29.  *
  30.  * Enjoy and contribute!
  31.  */
  32.  
  33. #include <string.h>
  34. #include "rb_plugin.h"
  35.  
  36. // this is the struct
  37. typedef struct {
  38.     long        check1;
  39.     long        check[3];    // fill up to 16 byte boundary
  40.     char        searchBuf[8192];
  41.     CSParam        pb;
  42.     FSSpec        spec;
  43.     CInfoPBRec    info1;
  44.     CInfoPBRec    info2;
  45.     Str27        volNameBuf;
  46.     long        check2;
  47. } CatSearchRec;
  48.  
  49. static Handle CatSearchOpen (REALfolderItem volIn)
  50. // this creates the struct (allocates memory for it)
  51. {
  52.     FSSpec fsSpec;
  53.     if (REALFSSpecFromFolderItem (&fsSpec, volIn)) {
  54.         Handle h = NewHandle (sizeof(CatSearchRec));
  55.         if (h && *h) {
  56.             // init the CatSearch fields
  57.             CatSearchRec *cs = (CatSearchRec*)*h;
  58.             CSParam &pb = cs->pb;
  59.             memset (cs, 0, sizeof (*cs));
  60.             pb.ioVRefNum = fsSpec.vRefNum;
  61.             pb.ioReqMatchCount = 1;
  62.             pb.ioOptBufSize = sizeof (cs->searchBuf);
  63.             cs->check1 = 'chk1';
  64.             cs->check2 = 'chk2';
  65.  
  66.             // invalidate the pointers in the pb so that noone tries to access them:
  67.             pb.ioNamePtr = (StringPtr)0x41414141;
  68.             pb.ioMatchPtr = (FSSpec*)0x41414141;
  69.             pb.ioSearchInfo1 = (CInfoPBRec*)0x41414141;
  70.             pb.ioSearchInfo2 = (CInfoPBRec*)0x41414141;
  71.             pb.ioOptBuffer = (Ptr)0x41414141;
  72.  
  73.             return h;
  74.         }
  75.     }
  76.     return nil;
  77. }
  78.  
  79. static void CatSearchClose (Handle h)
  80. // this releases the memory for the struct again
  81. {
  82.     if (h) {
  83.         CatSearchRec *cs = (CatSearchRec*)*h;
  84.         if (cs->check1 != 'chk1' || cs->check2 != 'chk2') {
  85.             DebugStr ("\pError in CatSearch-Plugin: bad handle passed");
  86.         } else {
  87.             DisposeHandle (h);
  88.         }
  89.     }
  90. }
  91.  
  92. static long CatSearchSetFileType (Handle h, REALstring fileType)
  93. // this sets some of the struct's values
  94. {
  95.     if (h) {
  96.         CatSearchRec *cs = (CatSearchRec*)*h;
  97.         if (cs->check1 != 'chk1' || cs->check2 != 'chk2') {
  98.             DebugStr ("\pError in CatSearch-Plugin: bad handle passed");
  99.         } else {
  100.             const unsigned char* ftStr = REALPString (fileType);
  101.             OSType ftype = *(OSType*)&ftStr[1];
  102.             cs->info1.hFileInfo.ioFlFndrInfo.fdType = ftype;
  103.             cs->info2.hFileInfo.ioFlFndrInfo.fdType = (UInt32) -1;    // mask
  104.             cs->info1.hFileInfo.ioFlAttrib &= ~ioDirMask;    // looking for files, not dirs
  105.             cs->info2.hFileInfo.ioFlAttrib |= ioDirMask;    // set the mask for files/dirs
  106.             cs->pb.ioSearchBits |= fsSBFlAttrib | fsSBFlFndrInfo;
  107.             return 1;
  108.         }
  109.     }
  110.     return 0;
  111. }
  112.  
  113. static long CatSearchSetCreator (Handle h, REALstring creator)
  114. // this sets some of the struct's values
  115. {
  116.     if (h) {
  117.         CatSearchRec *cs = (CatSearchRec*)*h;
  118.         if (cs->check1 != 'chk1' || cs->check2 != 'chk2') {
  119.             DebugStr ("\pError in CatSearch-Plugin: bad handle passed");
  120.         } else {
  121.             const unsigned char* cr = REALPString (creator);
  122.             OSType fc = *(OSType*)&cr[1];
  123.             cs->info1.hFileInfo.ioFlFndrInfo.fdCreator = fc;
  124.             cs->info2.hFileInfo.ioFlFndrInfo.fdCreator = (UInt32) -1;    // mask
  125.             cs->info1.hFileInfo.ioFlAttrib &= ~ioDirMask;    // looking for files, not dirs
  126.             cs->info2.hFileInfo.ioFlAttrib |= ioDirMask;    // set the mask for files/dirs
  127.             cs->pb.ioSearchBits |= fsSBFlAttrib | fsSBFlFndrInfo;
  128.             return 1;
  129.         }
  130.     }
  131.     return 0;
  132. }
  133.  
  134. static long CatSearchSetFileFlags (Handle h, long mask, long selector)
  135. // this adds specific File Flags to the Search Selection
  136. {
  137.     if (h) {
  138.         CatSearchRec *cs = (CatSearchRec*)*h;
  139.         if (cs->check1 != 'chk1' || cs->check2 != 'chk2') {
  140.             DebugStr ("\pError in CatSearch-Plugin: bad handle passed");
  141.         } else {
  142.             cs->info1.hFileInfo.ioFlFndrInfo.fdFlags = (cs->info1.hFileInfo.ioFlFndrInfo.fdFlags & ~mask) | (selector & mask);
  143.             cs->info2.hFileInfo.ioFlFndrInfo.fdFlags |= mask;
  144.             cs->info1.hFileInfo.ioFlAttrib &= ~ioDirMask;    // looking for files, not dirs
  145.             cs->info2.hFileInfo.ioFlAttrib |= ioDirMask;    // set the mask for files/dirs
  146.             cs->pb.ioSearchBits |= fsSBFlAttrib | fsSBFlFndrInfo;
  147.             return 1;
  148.         }
  149.     }
  150.     return 0;
  151. }
  152.  
  153. static long CatSearchNext (Handle h)
  154. // this performs the real action
  155. {
  156.     if (h) {
  157.         CatSearchRec *cs = (CatSearchRec*)*h;
  158.         if (cs->check1 != 'chk1' || cs->check2 != 'chk2') {
  159.             DebugStr ("\pError in CatSearch-Plugin: bad handle passed");
  160.         } else {
  161.             // since the CatSearchRec buffer might have been moved (it's not locked), we must
  162.             // set the pointers right before they're accessed:
  163.             CSParam &pb = cs->pb;
  164.             pb.ioNamePtr = cs->volNameBuf;
  165.             pb.ioMatchPtr = &cs->spec;
  166.             pb.ioSearchInfo1 = &cs->info1;
  167.             pb.ioSearchInfo2 = &cs->info2;
  168.             pb.ioOptBuffer = cs->searchBuf;
  169.             
  170.             OSErr err = PBCatSearchSync (&cs->pb);
  171.  
  172.             // invalidate them again so that noone tries to access them:
  173.             pb.ioNamePtr = (StringPtr)0x41414141;
  174.             pb.ioMatchPtr = (FSSpec*)0x41414141;
  175.             pb.ioSearchInfo1 = (CInfoPBRec*)0x41414141;
  176.             pb.ioSearchInfo2 = (CInfoPBRec*)0x41414141;
  177.             pb.ioOptBuffer = (Ptr)0x41414141;
  178.  
  179.             return err;
  180.         }
  181.     }
  182.     return -1;
  183. }
  184.  
  185. static REALfolderItem CatSearchGetItem (Handle h)
  186. // this retrieves one of the struct's values
  187. {
  188.     if (h) {
  189.         CatSearchRec *cs = (CatSearchRec*)*h;
  190.         if (cs->check1 != 'chk1' || cs->check2 != 'chk2') {
  191.             DebugStr ("\pError in CatSearch-Plugin: bad handle passed");
  192.         } else {
  193.             return REALFolderItemFromFSSpec (&cs->spec);
  194.         }
  195.     }
  196.     return NULL;
  197. }
  198.  
  199. static long VolSupportsCatSearch (REALfolderItem volIn)
  200. {
  201.     FSSpec fsSpec;
  202.     if (REALFSSpecFromFolderItem (&fsSpec, volIn)) {
  203.         IOParam pb;
  204.         GetVolParmsInfoBuffer buf;
  205.         pb.ioVRefNum = fsSpec.vRefNum;
  206.         pb.ioBuffer = (Ptr)&buf;
  207.         pb.ioReqCount = 6;
  208.         pb.ioNamePtr = nil;
  209.         if (PBHGetVolParmsSync ((HParmBlkPtr)&pb) == noErr && pb.ioActCount >= 6) {
  210.             if ((buf.vMAttrib & bHasCatSearch) != 0) return 1;
  211.         }
  212.     }
  213.     return 0;
  214. }
  215.  
  216.  
  217. REALexport pluginExports[] = {
  218.     { nil, CatSearchOpen },
  219.     { nil, CatSearchClose },
  220.     { nil, CatSearchSetFileType },
  221.     { nil, CatSearchSetCreator },
  222.     { nil, CatSearchNext },
  223.     { nil, CatSearchGetItem },
  224.     { nil, CatSearchSetFileFlags },
  225.     { nil, VolSupportsCatSearch },
  226. };
  227.  
  228. short pluginExportCode = sizeof(pluginExports) / sizeof(REALexport);
  229.  
  230. REALmethodDefinition methods[] = {
  231.     {0,    "CatSearchOpen(volume as FolderItem) as Integer"},
  232.     {1,    "CatSearchClose(handle as Integer)"},
  233.     {2,    "CatSearchSetFileType(handle as Integer, fileType as String) as Boolean"},
  234.     {3,    "CatSearchSetCreator(handle as Integer, creator as String) as Boolean"},
  235.     {4,    "CatSearchNext(handle as Integer) as Integer"},
  236.     {5, "CatSearchGetItem(handle as Integer) as FolderItem"},
  237.     {6,    "CatSearchSetFileFlags(handle as Integer, mask as Integer, selector as Integer) as Boolean"},
  238.     {7,    "VolSupportsCatSearch(volume as FolderItem) as Boolean"},
  239. };
  240.  
  241. void PluginEntry (void)
  242. {
  243.     for (int i = 0; i < pluginExportCode; ++i) {
  244.         REALRegisterMethod (&methods[i]);
  245.     }
  246. }
  247.